/* 
 *  Copyright 2012 CodeMagi, Inc.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.codemagi.servlets.content;

import com.codemagi.login.AccessException;
import com.codemagi.login.LoginException;
import com.codemagi.login.model.IUser;
import com.codemagi.servlets.AppException;
import com.codemagi.servlets.content.beans.PageSearchBean;
import com.codemagi.servlets.search.beans.ISearchBean;
import com.codemagi.util.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;


/**
 * SearchController implementation for searching page content.
 *
 * @version 1.0
 * @author August Detlefsen for CodeMagi, Inc.
 */
public class PageSearchController extends com.codemagi.servlets.search.SearchController {

    //create logger to view debug output
    Logger log = Logger.getLogger(this.getClass());

    //MEMBERS
    private static final HashMap sortClauses   = new HashMap(10);
    static {
	sortClauses.put("default", "SCORE(10) DESC");
    }


    /**                                                                                                                  
     * Initializes the controller                                                                  
     */
    public void init(ServletConfig config)
        throws ServletException {

        super.init(config);

        //override values of member vars                    
	beanName  = "pageSearchBean";
	beanClass = "com.codemagi.servlets.content.beans.PageSearchBean";

	VIEW_MAIN                 = "/pageSearch/index.jsp";
        VIEW_SEARCH               = "/pageSearch/index.jsp";
        VIEW_RESULTS              = "/pageSearch/results.jsp";
    }


    /**
     * Dispatches <code>Search</code> actions.
     */
    protected String dispatchSearch(HttpServletRequest request, HttpServletResponse response)
        throws LoginException, AccessException {

        log.debug("***** dispatchSearch *****");

        //next page if operation is successful
        String nextPage = VIEW_RESULTS;

	//get session
        HttpSession session = request.getSession();

        try {
	    //get a fresh search bean
	    PageSearchBean bean = new PageSearchBean();

	    //get search params
	    String keywords           = request.getParameter("keywords");
	    IUser user                = (IUser)session.getAttribute("user");

	    //set new values in the bean
	    bean.setKeywords(keywords);
	    bean.setUser(user);

	    //generate a new query from the search params
	    generateQuery(bean);

	    //set the search bean into the session
	    session.setAttribute("pageSearchBean", bean);

	} catch (AppException se) {
	    log.debug("", se);

	    request.setAttribute("error_message", se.getMessage());

	    nextPage = VIEW_SEARCH;

	}
	    
	return nextPage;
    }


    /**
     * Generates the actual query used for the search
     */
    protected void generateQuery(ISearchBean ibean) throws AppException{

	try {
	    PageSearchBean bean = (PageSearchBean)ibean;

	    //GENERATE QUERY ----------------------
	    //generate conditional clauses based on the search terms submitted
	    String keywords = bean.getKeywords();
            StringBuffer keywordsClause = new StringBuffer(100);
            if ( !Utils.isEmpty(keywords) ) {
		keywordsClause.append(" AND CONTAINS(st.content, '");

                StringTokenizer st = new StringTokenizer(keywords);
                StringBuffer buffer = new StringBuffer(st.countTokens() * 64);

                while (st.hasMoreTokens()) {
                    String keyword = st.nextToken();
		    keywordsClause.append( "$" + DbUtils.escape(keyword) + "%" );

		    if (st.hasMoreTokens()) keywordsClause.append( ", " );
                }
		keywordsClause.append("', 10)>0 ");
            }

	    //control who can search for what
	    IUser user = bean.getUser();
	    StringBuffer accessClause = new StringBuffer();

	    if (user == null || user.getId() == null || !user.isAuthenticated()) {
		accessClause.append(" AND p.login_reqd_tf = 'F' ");
	    }

	    //determine how to order results
	    String orderBy = bean.getSortBy();
	    String orderByClause = (String)sortClauses.get( bean.getSortBy() );
	    if (Utils.isEmpty(orderByClause)) orderByClause = (String)sortClauses.get("default");

	    //construct the whole query
	    String query = " SELECT p.page_id, p.name, p.link, substr(strip_long_html(p.content), 0, 100) AS content, " + 
		" SCORE(10) AS score, TO_CHAR(p.content_date, 'MM/DD/YYYY') AS contentDate " + 
		" FROM nav_page p, nav_page_search_text st " + 
		" WHERE p.page_id = st.page_id " + 
		keywordsClause.toString() + 
		accessClause.toString() + 
		" ORDER BY " + orderByClause;

	    //store the new query in the bean
	    bean.setQuery(query);


        } catch (Exception e) {
            log.info("generateQuery(): Error casting ISearchBean", e);
            throw new AppException(MSG_UNKNOWN_ERROR);
        }

    }

}
